package Tabulate(tabulate) where

import List
import Enum

--@ \subsubsection{Tabulate}
--@
--@ \index{Tabulate@\te{Tabulate} (package)|textbf}
--@ The \te{tabulate} function can be used to tabulate an
--@ arbitrary function (given the type constraints).
--@ This means that that the function will be precomputed for
--@ its argument at compile time and the right value will be
--@ selected at run time by a case expression.
--@
--@ This is a powerful function that captures several design
--@ patterns where a mux is used.
--@
--@ \index{tabulate@\te{tabulate} (\te{Tabulate} function)}
--@ \begin{libverbatim}
--@ function b tabulate(function b f(a x1), a x)
--@   provisos (Bounded#(a), Bits#(a, sa));
--@ \end{libverbatim}
tabulate :: (Bounded a, Bits a sa) => (a -> b) -> (a -> b)
tabulate f x =
--    foldr (\ b r -> if pack x == pack b then f b else r) _ enumAll
--    foldr (\ b r -> if x == b then f b else r) _ enumAll

    let lo :: Bit sa
        lo = pack (minBound::a)
        hi :: Bit sa
        hi = pack (maxBound::a)
    in  foldr (\ b r -> if pack x == b then f (unpack b) else r) _ (enumFromTo lo hi)

--@ {\bf NOTE}, the \te{tabulate} function uses comparison of the bit
--@ representations of the type \qbs{a} to decide equality.  This may
--@ not behave like the defined equality for the type.
